package com.ling.feign.plus.config;

import com.ling.feign.plus.context.FeignEnvironmentAware;
import com.ling.feign.plus.support.FeignServerBusinessExceptionResolver;
import com.ling.feign.plus.support.FeignServerExceptionDecoder;
import feign.Feign;
import feign.RequestInterceptor;
import feign.Retryer;
import feign.codec.ErrorDecoder;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import static com.ling.feign.plus.FeignExceptionConstant.FEIGN_CALLER_HEADER;

/**
 * feign相关配置项
 */
@Configuration
@ConditionalOnClass({Feign.class})
@AutoConfigureBefore(WebMvcAutoConfiguration.class)
public class FeignConfiguration {

    /**
     * 设置feign Retry次数
     * 不重试
     */
    @Bean
    @ConditionalOnMissingBean
    public Retryer feignRetry() {
        return Retryer.NEVER_RETRY;
    }



    /**
     * 业务异常解码器
     * feign-client端使用
     */
    @Bean
    @Primary
    public ErrorDecoder getErrorDecoder() {
        return new FeignServerExceptionDecoder();
    }


    /**
     * feign-server端使用
     * 捕捉被调用服务内抛出的异常
     * 捕获异常并JSON序化返回
     */
    @Bean
    @Primary
    @ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)
    public DefaultErrorAttributes errorAttributes() {
        return new FeignServerBusinessExceptionResolver();
    }

    @Bean
    public RequestInterceptor requestInterceptor() {
        return template -> template.header(FEIGN_CALLER_HEADER, FeignEnvironmentAware.getApplicationName());
    }

}
